package com.demo.websocket;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
@ServerEndpoint("/websocketIpc/{id}")
public class WebsocketIpcServer {

    private static final Logger log = LoggerFactory.getLogger(com.demo.websocket.WebsocketIpcServer.class);

    private static int onlineCount = 0;

    private static ConcurrentHashMap<String, com.demo.websocket.WebsocketIpcServer> webSocketSet = new ConcurrentHashMap<>();

    private Session session;

    private String id = "";

    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session, EndpointConfig config) {
        this.session = session;
        this.id = id;
        webSocketSet.put(id, this);
        addOnlineCount();
        log.info("用户编号：" + id + "加入！当前在线人数为：" + getOnlineCount());
        try {
            Map<String, String> map = new HashMap<>();
            map.put("code", "200");
            map.put("msg", "成功");
            String result = JSONUtil.toJsonStr(map);
            sendMessage(result);
        } catch (IOException e) {
            log.error("websocket IO异常");
        }
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this.id);
        subOnlineCount();
        log.info(this.id + "连接关闭！当前在线人数为：" + getOnlineCount());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("来自客户端的消息" + message);
        log.info("onMessage sessionId is : " + session.getId());
        try {
            Map<String, String> map = new HashMap<>();
            map.put("code", "200");
            map.put("msg", "成功");
            String result = JSONUtil.toJsonStr(map);
            sendToUser(result, session.getId());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    public void sendToUser(String message, String sendUserId) throws IOException {
        String[] ids = sendUserId.split(",");
        int conut = 0;
        for (int i = 0; i < ids.length; i++) {
            String userId = ids[i];
            if (webSocketSet.get(userId) != null) {
                if (!this.id.equals(userId)) {
                    (webSocketSet.get(userId)).sendMessage("用户" + this.id + "发来消息：<br/> " + message);
                } else {
                    conut++;
                }
                (webSocketSet.get(sendUserId)).sendMessage(message);
            } else {
                conut++;
            }
        }
    }

    /**
     * 给当前所有用户发送设备运行数据
     */
    public void sendToAll(String message) throws IOException {
        log.info("websocketIpc在线用户列表 webSocketSet={}", JSON.toJSONString(webSocketSet));
        for (String key : webSocketSet.keySet()) {
            try {
                (webSocketSet.get(key)).sendMessage(message);
                log.info("发送消息为：" + message);
            } catch (IOException e) {
                log.error("发送消息错误", e);
                throw new IOException(e.getMessage());
            }
        }
    }

    public List<Integer> getAllSocketUser() {
        List<Integer> list = new ArrayList<>();
        for (String key : webSocketSet.keySet())
            list.add(Integer.valueOf(Integer.parseInt(key)));
        log.info("当前 websocket 中所有用户集合：--" + list);
        return list;
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
    }
}
